<?php
/**
 * centralised log
 * provides functions to
 * either log in memory
 * and save at last bit
 * or
 * log in file directly - save every time
 * it also has benchmarking functionalities to include for functions
 * @author bbqq <toughgamer@gmail.com>
 * @package com.blib.utility
 * @copyright bbqq qstufie.com
 */
class Blib_Utility_Log
{
    /**
     * the path to log file
     * @var str
     */
    private $_logPath = null;


    /**
     * the buffer
     */
    private $_buffer = null;


    /**
     * start it up!
     */
    public function __construct($path)
    {
        // log must be there already, no compromises!
        if (!file_exists($path)) {
            if (!@touch($path)) {
                throw new exception('LOG [' . $path . '] can not be created!');
            }
        }

        // otherwise, save it to self's path
        $this->_logPath = $path;

    }// end __construct


    /**
     * save log
     * @param str $msg message to save
     * @return self
     */
    private function _saveLog($msg)
    {
        // trial and fail - unfortunately file put contents doesnt give u exceptions
        if (!@file_put_contents($this->_logPath, $msg, FILE_APPEND)) {
            throw new exception('Unable to save to log file: ' . $this->_logPath);
        }

        return $this;

    }// end _saveLog


    // clear buffer
    private function _clearBuffer()
    {
        $this->_buffer = null;
        return $this;

    }// end _clearBuffer


    /**
     * save a log!
     * @param str $message the actual log message
     * @param bool $save if true, save it right away
     * @param bool $echo if true, also echo the log...
     * @return self
     */
    public function log($message, $save = true, $echo = true)
    {
        $message = $this->composeLog($message);

        // add: let's echo it out, shall we?
        // only running as cli...
        if (php_sapi_name() == 'cli' && $echo) {
            echo $message;
        }

        // if not save, attach to buffer
        if (!$save) {
            $this->_buffer .= $message;
            return $this;
        }

        // else only save this and clean buffer
        $this->_saveLog($message);
        return $this->_clearBuffer();

    }// end log


    /**
     * save buffer into log file
     * and clear buffer
     */
    public function save()
    {
        if (!empty($this->_buffer)) {
            $this->_saveLog($this->_buffer);
        }

        return $this->_clearBuffer();

    }// end save


    /**
     * read out loud!
     * @return str the entire log or limited by line num
     */
    public function read()
    {
        return @file_get_contents($this->_logPath);

    }// end read


    /**
     * clear the damn file
     * @return $this;
     */
    public function clear()
    {
        return @file_put_contents($this->_logPath, '');

    }// end clear


    /**
     * how to compose the log?
     */
    public function composeLog($message)
    {
        // first of all, message must be clear of new spaces
        // always use utc time
        $msg = gmdate('Y-m-d H:i:s');
        // micro seconds?
        $u = explode('.', microtime(1));
        if (empty($u[1])) {
            $u[1] = 0.00;   // default...
        }
        $msg .= ':' . $u[1];
        unset($u);
        // now the message
        $msg .="    $message\n";
        return $msg;

    }// end composeLog


    /**
     * rotate the log file by dates
     * @param str $name, the name of log (sans the .log extension)
     * @param str $path the path where it resides.
     * @return void.
     */
    public static function rotateLog($name, $path)
    {
        // take the src, and take a name for it...
        $src = $path . $name . '.log';
        if (!file_exists($src)) {
            return false;
        }

        /**
         * there will be a memory problem when reading excessive amount of data
         * so make sure to use mv to do the job
         */
        /*
        $data = file_get_contents($src);
        if (empty($data)) {
            // no point to rotate empty data...
            return false;
        }
        */

        // first, is it the time of the day yet? we only do it once a day...for previous day.
        $date = date('Ymd', strtotime('yesterday'));
        $targ = $path . $name . '.log.' . $date;

        // if already exists, don't do it...
        if (file_exists($targ)) {
            return true;
        }

        // otherwise, rotate and clean main log
        // mv
        passthru('cp "' . $src . '" "' . $targ . '"');
        // recreate src
        passthru('echo >  "' . $src . '"');

        // @file_put_contents($targ, $data);
        // @file_put_contents($src, ' ');

    }// end rotateLog

}// end Blib_Utility_Log
?>